﻿//===========================[ 7 / 17 / 2011 LVI ]=============================
//				Copyright c Vitaly Lyaschenko <SkyChameleon@gmail.com>
// 								Header file
// Purpose: 
//=============================================================================
#pragma once

#include "common.h"
#include "Vertices.h"

enum optType
{	
	UNKNOWN                 =-1,
	NO                      = 0,
	WELD_VERTICES           = 7,
	CACHE_FACES_OPTIMIZE    = 8,
	CACHE_VERTICES_OPTIMIZE = 9,
	TOTAL_OPTIMIZE          = 15,
};

struct HeaderModel
{   
	int numMesh;
	char userData[128];
	optType m_format;
};

class cSubMesh
{
public:
	cSubMesh();
	~cSubMesh();
	// поумолчанию используется буфер индесов
	bool isIndices;
	char name[128];
	// индексы полигона размером в 16 бит используется с флагом GL_UNSIGNED_SHORT в glDrawElements
	std::vector<_16ubit> m_Indices;
	// контейнер для вершин (position/normal/texcoor)
	std::vector<Vertex_PNT> m_Vertices;

	// флаг использования индексов
	void useIndices( const bool isIndx ) { isIndices = isIndx; }

	// возвращает указатель на начало массива вертексов/индексов
	Vertex_PNT& beginVert() { return m_Vertices.front(); }
	_16ubit& beginIndx()    { return m_Indices.front();  }

	// получить общее количество полиглнов/вершин/индексов в модели
	// (p.s. при оптимизации кол-во вершин != кол-ву индексов)
	ulong getNumFaces()    const { return m_Vertices.size() / 3; }
	ulong getNumVertices() const { return m_Vertices.size();     }
	ulong getNumIndices()  const { return m_Indices.size();      }

	// установить количество вершин/индексов в модели
	void setNumVertices( ulong num_Vertices )
	{
		ASSERT( num_Vertices > 0 );
		m_Vertices.resize( num_Vertices );
	}
	void setNumIndices( ulong num_Indices )
	{
		ASSERT( num_Indices > 0 );
		m_Indices.resize( num_Indices );
	}
	// установить вертекс/индекс модели
	void setVertex( Vertex_PNT vert ) {	m_Vertices.push_back( vert ); }
	void setIndex( _16ubit indx ) { m_Indices.push_back( indx ); }
};

class cMesh
{
public:
	cMesh(void);
	~cMesh(void);

	HeaderModel hData;
	std::vector< cSubMesh* > meshes;

	uint getNumMesh() const { return meshes.size(); }

	void createMesh()
	{
		meshes.push_back( new cSubMesh );
		hData.numMesh++;
	}
	cSubMesh* lastMesh()
	{
		return meshes.back();
	}
	// обращение к части модели
	cSubMesh* at( int n ) { return meshes[n]; }

	void setHeaderModelData( HeaderModel &dat ) {  hData = dat; }

private:
	void clearData();
};